package gbench.appdemo.mall.junit;

import org.junit.jupiter.api.Test;

import gbench.appdemo.mall.erp.MyPlatform;
import gbench.appdemo.mall.erp.components.IEnterprise;
import gbench.appdemo.mall.erp.components.IProduct;
import gbench.common.matlib.MatlibCanvas.XVec;
import gbench.common.tree.LittleTree.SQL;

import java.util.stream.Collectors;
import java.util.stream.Stream;

import static gbench.common.matlib.MatlibCanvas.println;
import static gbench.common.matlib.rdd.BasePair.bp;
import static gbench.common.tree.LittleTree.IRecord.*;
import static gbench.common.tree.LittleTree.Term.FT;
/**
 * 
 * @author gbench
 *
 */
public class JunitErp {
    
    /**
     * 为企业生成产品目录
     */
    @Test
    public void foo() {
        final var platform = new MyPlatform();
        platform.withTransaction(erpApp->{
            final var pcts = erpApp.sqlqueryS("select * from t_product").map(erpApp.ctor(IProduct.class)).collect(XVec.xveclc());
            erpApp.sqlqueryS("select * from t_fortune limit 110")
            .map(erpApp.ctor(IEnterprise.class))
            .forEach(e->{
                println(e);
                final var catalog = e.catalogX("主营产品");
                if(catalog==null) {
                    final var c = e.buildCatalog(REC("name","主营产品","symbol","PRIMARY"), 0.5*Math.random(), 0.17, pcts.shuffle().head(20).fmap(p->bp(p, p.getPrice().mul(1.2))));
                    println("新的产品目录",c);
                }else {
                    println(catalog);
                }// if
            });
            
            return null;
        });
        
        println(SQL.of("user",REC("name","zhangsan","sex","lisi"),REC("address","shanghai")).select("name,sex,address","and","or"));
    }
    
    @Test
    public void credit() {
        final var platform = new MyPlatform();
        platform.withTransaction(erpApp->{
            final var partA = erpApp.getEnterprise(1, true);
            final var partB = erpApp.getEnterprise(2, true);

            // partA 设置企业 partB 的 信用额度
            partA.updateCredit(partB, v -> {
                return v == null ? 100d : v + 100d;
            });

            // partB 设置企业 partA 的 信用额度
            partB.updateCredit(partA, v -> {
                return v == null ? 100d : v + 200d;
            });

            println(partA, partB, "的信用额度", partA.getCredit2(partB));
            println(partB, partA, "的信用额度", partB.getCredit2(partA));
            
            final var catalogName = "主营产品";
            var catalogX = partB.catalogX(catalogName); // 提取产品目录
            if (catalogX == null) {// 生成一个
                final var pcts = erpApp.sqlqueryS("select * from t_product").map(erpApp.ctor(IProduct.class)).collect(XVec.xveclc());
                catalogX = partB.buildCatalog(REC("name", catalogName, "symbol", "PRIMARY"), 0.2, 0.17,
                        pcts.head(20).fmap(p -> bp(p, p.getPrice().mul(1.2)))).collect(XVec.xveclc());
                println(FT("创建了一个 $0 产品目录",catalogName));
            }// if
            println(partB, catalogName, catalogX);
            
            catalogX.resize(200).shuffle().slice(20)
            .forEach(xvec -> { // 生成订单
                final var orderLines = xvec.groupByX(o -> o, XVec::OF).fmap(p -> p.fmap2(XVec::size)).fmap(erpApp.priceQuote2lineItem()); // 生成订单行项目
                final var po = partA.purchase(partB, orderLines); // 生成订单
                println(po);
                po.forEach(e -> {
                    println(e, e.getProduct().getPrice());
                });
                po.persist();
                println("Total:",po.getTotal());
            });
            
            // 修改产品报价单
            partB.catalogOf(catalogName).update(catalogX.list(e->REC("product",e.getProduct(),"price",e.getUnitPrice().getAmount()*1.1,"tax",0.12)));
            
            // 指定具体产品名称的修改
            partB.catalogOf(catalogName).update( Stream.of("面粉,面粉1,冰鲜耗儿鱼,冻豆腐".split(",")) // 产品清单
                .map(name->REC("product",erpApp.productOf(name),"price",100,"tax",0.17))
                .collect(Collectors.toList())
            );
            
            // 删除指定产品
            //partA.catalogOf("我的煎饼").remove( Stream.of("冰鲜耗儿鱼,冻豆腐".split(",")).map(erpApp::productOf).collect(Collectors.toList()));
            
            partA.getPuchaseOrders().forEach(e -> {
                println("------------------",e);
            });
            return partA;
        });
    }

}
